/**
 * The Free Gaming System; fake game server to test the game
 * integration library.
 *
 * Copyright 2006 the Free Gaming System developers.
 *
 * FGS is the legal property of its developers, whose names are too
 * numerous to list here.  Please refer to the COPYRIGHT file
 * distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "fgs_game.h"

char *test_data =
"FGS\n"
"CLIENT\n"
"0.2\n"
"\0\n"
"LOGIN\n"
"dave\n"
"48358934828539482928953\n"
"\0\n";
int len_test_data = 54;

int test_data_idx = 0;

#define TEST(expr, err)                         \
  do {                                          \
    fgs_error_t fgs_err__temp = (expr);         \
    if (fgs_err__temp != FGS_OK)                \
      { printf("%s\nError %s\n", err,           \
        fgs_strerror(fgs_err__temp));           \
        exit(1); }                              \
  } while (0)

fgs_error_t
read_client(fgs_baton_t b, char *s, int l, fgs_bool_t q)
{
  /*  printf("Read %d from test string\n", l); */
  if (len_test_data - test_data_idx < l)
    return FGS_ERR_SOCKET_ERROR;

  memcpy(s, &test_data[test_data_idx], l);

  if (q)
    test_data_idx += l;
  /*  printf("Read OK.\n"); */
  return FGS_OK;
}

fgs_error_t
write_client(fgs_baton_t b, char *d, int l)
{
  return FGS_OK;
}

fgs_bool_t
cmp_client(fgs_baton_t b, fgs_baton_t b2)
{
  return b == b2 ? FGS_TRUE : FGS_FALSE;
}

void
append_config(char *k, char *v)
{
  printf("Received configuration from the proxy: %s = %s\n", k, v);

  return;
}

int main(int argc, char **argv)
{
  fgs_callbacks_t *cb;
  fgs_ctx_t *ctx;
  fgs_uuid_t uuid1, uuid2, muuid;

  printf("Initializing callbacks...\n");
  TEST(fgs_init_callbacks(&cb, FGS_NONE), "Error initializing callbacks");

  cb->read_client = read_client;
  cb->write_client = write_client;
  cb->cmp_client = cmp_client;
  cb->append_config = append_config;

  printf("Connecting and registering to proxy...\n");
  TEST(fgs_init(&ctx, "testlib", "0.1", 4242, cb), "Failed to init the fgs lib");

  printf("Requesting configuration from the proxy...\n");
  TEST(fgs_process_config(ctx), "Error during config retrieval");

  printf("Player 1 connecting...");
  TEST(fgs_new_player(ctx, &uuid1, (fgs_baton_t)0xDEADBEEF, FGS_TRUE),
       "Error during new player 1 handling");
  TEST(fgs_update_player(ctx, uuid1, "PlayerName", FGS_STRING, "Player1"),
       "Error during player updating");

  printf("Player 2 connecting...");
  TEST(fgs_new_player(ctx, &uuid2, (fgs_baton_t)0xBABE, FGS_TRUE),
       "Error during new player 2 handling");
  TEST(fgs_update_player(ctx, uuid2, "PlayerName", FGS_STRING, "Player2"),
       "Error during player updating");

  printf("Committing players...\n");
  TEST(fgs_commit_player(ctx, NULL),
       "Error during committing of players");

  printf("Creating a match...\n");
  TEST(fgs_new_match(ctx, &muuid),
       "Error during creation of match");
  TEST(fgs_update_match(ctx, muuid, "GameStatus", FGS_STRING, "Running"),
       "Error during updating of match");

  printf("Committing match...\n");
  TEST(fgs_commit_match(ctx, NULL),
       "Error during committing of match");

  printf("Adding player 2 to match...\n");
  TEST(fgs_join_match(ctx, muuid, uuid1),
       "Error during player 1 join of a match");
  TEST(fgs_join_match(ctx, muuid, uuid2),
       "Error during player 2 join of a match");

  TEST(fgs_update_match_player(ctx, muuid, uuid1, "PlayerStatus",
                               FGS_STRING, "Playing"),
       "Error updating match/player info");
  TEST(fgs_update_match_player(ctx, muuid, uuid2, "PlayerStatus",
                               FGS_STRING, "Spectator"),
       "Error updating match/player info");

  printf("Player 1 is leaving match...\n");
  TEST(fgs_leave_match(ctx, muuid, uuid1),
       "Error during player 2 leaving of a match");
  printf("Player 2 is leaving match...\n");
  TEST(fgs_leave_match(ctx, muuid, uuid2),
       "Error during player 2 leaving of a match");

  printf("Deleting the match...\n");
  TEST(fgs_end_match(ctx, muuid),
       "Error during ending of match");

  printf("Removing first client...\n");
  TEST(fgs_remove_player(ctx, uuid1),
       "Error during player 1 removal");
  printf("Removing second client...\n");
  TEST(fgs_remove_player(ctx, uuid2),
       "Error during player 2 removal");

  free(uuid1);
  free(uuid2);

  printf("Now shutting down...\n");
  TEST(fgs_shutdown(ctx), "Error during proxy shutdown");

  return 0;
}
